#ifndef __BLOCK_QUEUE_HPP__
#define __BLOCK_QUEUE_HPP__

#include<iostream>
#include<string>
#include<queue>
#include<pthread.h>

template<class T>
class Blockqueue
{
    private:
    bool IsFull()
    {
        return _block_queue.size()==_cap;
    }
    bool IsEmpty()
    {
        return _block_queue.empty();
    }
    public:
    //构造
    Blockqueue(int cap)
    :_cap(cap)
    {
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_product_cond,nullptr);
        pthread_cond_init(&_consum_cond,nullptr);
    }
    void Enqueue(T &in)//生产者
    {
        //1：pthread_cond_wait调用时：a让条用线程等待，b自动释放曾经持有的锁，c 当条件满足线程唤醒
        //pthread_cond_wait要求线性,必须重新竞争锁，竞争成功返回，
        //上锁
        pthread_mutex_lock(&_mutex);
        if(IsFull())
        {
            pthread_cond_wait(&_product_cond,&_mutex);
        }
        //--------一下是临界区
        //判断资源是否为满
      std::cout<<in<<std::endl;
      _block_queue.push(in);
      pthread_cond_signal(&_consum_cond);
      pthread_mutex_unlock(&_mutex);
    }
    //消费者
    void pop(T *out)
    {
        pthread_mutex_lock(&_mutex);
        if(IsEmpty())
        {
            pthread_cond_wait(&_consum_cond,&_mutex);
        }
        *out = _block_queue.front();
        _block_queue.pop();
        pthread_cond_signal(&_product_cond);
        pthread_mutex_unlock(&_mutex);
        
    }
    ~Blockqueue()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_product_cond);
        pthread_cond_destroy(&_consum_cond);
    }
    private:
    std::queue<T> _block_queue;//阻塞队列
    int _cap;//整体熔炼
    pthread_mutex_t _mutex;
    pthread_cond_t _product_cond;//专门给生产者提供的条件变脸
    pthread_cond_t _consum_cond;//消费的的条件变量
};

#endif